

use hyper::Client;
use hyper::rt::{self, Future, Stream};
use hyper::{Method, Request, Body};
use hyper::header::{HeaderValue};
use std::io::{self, Write};

// ===================================================================================== http get post

// fn httpclient(n: i32) -> Result {
//     let mut core = Core::new()?;
//     let client = Client::new(&core.handle());
    
//     let uri = "http://httpbin.org/ip".parse()?;
//     let work = client.get(uri).and_then(|res| {
//         println!("Response: {}", res.status());

//         res.body().for_each(|chunk| {
//             io::stdout()
//                 .write_all(&chunk)
//                 .map_err(From::from)
//         })
//     });
//     core.run(work)?;
//     return std::ptr::null; //(std::ptr::null, std::ptr::null)
// }

pub fn httpclient_get() {
    rt::run(rt::lazy(|| {
        // This is main future that the runtime will execute.
        //
        // The `lazy` is because we don't want any of this executing *right now*,
        // but rather once the runtime has started up all its resources.
        //
        // This is where we will setup our HTTP client requests.
        let client = Client::new();

        let uri = "http://httpbin.org/ip".parse().unwrap();

        client
            .get(uri)
            .and_then(|res| {
                println!("Response: {}", res.status());
                res
                    .into_body()
                    // Body is a stream, so as each chunk arrives...
                    .for_each(|chunk| {
                        io::stdout()
                            .write_all(&chunk)
                            .map_err(|e| {
                                panic!("example expects stdout is open, error={}", e)
                            })
                    })
            })
            .map_err(|err| {
                println!("Error: {}", err);
            })
    }));
}

pub fn httpclient_get2() {
    rt::run(rt::lazy(|| {
        // This is main future that the runtime will execute.
        //
        // The `lazy` is because we don't want any of this executing *right now*,
        // but rather once the runtime has started up all its resources.
        //
        // This is where we will setup our HTTP client requests.
        let client = Client::new();

        let uri = "http://httpbin.org/ip".parse().unwrap();

        client
            .get(uri)
            .map(|res| {
                println!("Response: {}", res.status());
            })
            .map_err(|err| {
                println!("Error: {}", err);
            })
    }));
}

pub fn httpClient_post1(){
    rt::run(rt::lazy(|| { // y运行一个 懒闭包 
        let json = r#"{"library":"hyper"}"#; // e"##" 格式应该是能 包含双引号的格式
        let uri: hyper::Uri = "http://httpbin.org/post".parse().unwrap();
        let mut req = Request::new(Body::from(json));
        *req.method_mut() = Method::POST;
        *req.uri_mut() = uri.clone();
        req.headers_mut().insert(
            hyper::header::CONTENT_TYPE,
            HeaderValue::from_static("application/json")
        );
        let client = Client::new();
        let post = client.request(req).and_then(|res| {
            println!("POST: {}", res.status());
            res.into_body().concat2()
        });
        let get = client.get("http://httpbin.org/headers".parse().unwrap()).and_then(|res| {
            println!("GET: {}", res.status());
            res.into_body().concat2()
        });
        let work = post.join(get);

        work
            .map(|(posted, got)| {
                println!("GET: {:?}", got);
                println!("POST: {:?}", posted);
            })
            .map_err(|err| {
                println!("Error: {}", err);
            })
    }));
}

pub fn httpClient_newuser(){
    rt::run(rt::lazy(|| {
        let json = r#"{"Account":"admin", "Password": "112233"}"#;
        let uri: hyper::Uri = "http://localhost:9031/api/Account/Insert".parse().unwrap();
        let mut req = Request::new(Body::from(json));
        *req.method_mut() = Method::POST;
        *req.uri_mut() = uri.clone();
        req.headers_mut().insert(
            hyper::header::CONTENT_TYPE,
            HeaderValue::from_static("application/json")
        );
        let client = Client::new();

        client
            .request(req)
            .and_then(|res| {
                println!("Response: {}", res.status());
                res
                    .into_body()
                    // Body is a stream, so as each chunk arrives...
                    .for_each(|chunk| {
                        io::stdout()
                            .write_all(&chunk)
                            .map_err(|e| {
                                panic!("example expects stdout is open, error={}", e)
                            })
                    })
            })
            .map_err(|err| {
                println!("Error: {}", err);
            })
    }));
}

// "http://localhost:9031/api/Account/Insert"
// r#"{"Account":"admin", "Password": "112233"}"#

pub fn httpClient_post(url: String, json_str: String){
    rt::run(rt::lazy(move|| {
        let json = json_str;// r#"{"Account":"admin", "Password": "112233"}"#;
        let uri: hyper::Uri = url.parse().unwrap();
        let mut req = Request::new(Body::from(json));
        *req.method_mut() = Method::POST;
        *req.uri_mut() = uri.clone();
        req.headers_mut().insert(
            hyper::header::CONTENT_TYPE,
            HeaderValue::from_static("application/json")
        );
        req.headers_mut().insert(
            hyper::header::COOKIE,
            HeaderValue::from_static(r#"app_client_key=db8ba6f567e44fd1bc45fae794141e32; CurrectSso=1; SSO_App_Ocss6=9AEB81CC2B788AC53B561C1F3D69338F413FEF1B4E9BB5F4A2284D30E2B0F7E9A4D763B62EABDB38A070113887FE848EA4C1DE66E9C208DAA33A95EA78C4E6875511517CE283201065070CB5D69789F2F439B6B6933C85F9594B0FE5939DEA40536DDC3EC9D5E283A17A851EB7447B01A9849D4AA1B59E7FE1C04281D13DA41D210505DA3084AD5D86A26CDE69C1F507563D29792A03D1BACF1DFEE73AFA0D1D"#)
        );
        let client = Client::new();

        client
            .request(req)
            .and_then(|res| {
                println!("Response: {}", res.status());
                res.into_body()
                    // Body is a stream, so as each chunk arrives...
                    .for_each(|chunk| {
                        io::stdout()
                            .write_all(&chunk)
                            .map_err(|e| {
                                panic!("example expects stdout is open, error={}", e)
                            })
                    })
            })
            .map_err(|err| {
                println!("Error: {}", err);
            })
    }));
}